/**
 * 服务端响应的错误码
 */
// eslint-disable-next-line max-classes-per-file
export const ErrorCode = {
  SUCCESS: 0,
  USER_OFFLINE: 1,
  PUSH_TO_CLIENT_FAILURE: 2,
  ROUTER_CHANGE: 3,
  ACK_TIME_OUT: 4,
  HANDLE_MESSAGE_ERROR: 100,
  UNSUPPORTED_COMMAND: 101,
  REPEAT_HANDSHAKE: 102,
  SESSION_EXPIRED: 103,
  INVALID_DEVICE: 104,
  TOKEN_OVERDUE: 1012,
  UNKNOWN: -1,
};

/**
 * 服务端错误码的说明
 */
const ErrorCodeDesc = {
  0: '成功',
  1: '用户离线',
  2: '推送失败',
  3: '路由变化，用户连接路由变化',
  4: 'ack 超时',
  100: '消息处理失败',
  101: '不支持消息类型',
  102: '重复握手',
  103: 'session过期，快速连接进行判断session时效性判断',
  104: '快速连接是session对应的设备与服务端保持的设备不一致',
  [-1]: '未知错误',
};

const ConnStatusDesc = {
  [-1]: '连接过程失败',
  0: '默认状态 -> 连接中',
  1: '连接成功->开始握手',
  2: '握手成功 -> 绑定用户',
  3: '绑定用户成功 -> 就绪通知',
  4: '一切就绪',
};

/**
 * 连接错误
 */
export class ConnectError {
  status = -1;

  name = 'ConnectError';

  text = '连接失败报错';

  repeat = 0;

  desc = '';

  isLastTry = null;

  /**
   * 连接错误
   * @param status{CONN_STATUS} 连接状态
   * @param repeat 重试次数
   * @param isLastTry
   */
  constructor(status, repeat, isLastTry = false) {
    // this.isLastTry = repeat ===
    this.status = status;
    this.desc = `[失败] ` + (ConnStatusDesc[status] || '未知错误');
    this.repeat = repeat;
    this.isLastTry = isLastTry;
    // console.warn(this)
  }
}

/**
 * 超时错误
 */
export class ResponseTimeoutError {
  name = 'ResponseTimeoutError';

  desc = '响应超时错误';

  requestId = 0;

  timeout = 0;

  /**
   * @param requestId 请求id
   * @param timeout 超时设定的时长
   */
  constructor(requestId, timeout) {
    this.requestId = requestId;
    this.timeout = timeout;
    console.warn(this);
  }
}

/**
 * 响应错误
 */
export class ResponseError {
  name = 'ResponseError';

  desc = '响应错误';

  code = null;

  reason = '';

  data = null;

  cmd = null;

  /**
   * @param body 响应体
   */
  constructor(body) {
    const { cmd, code, reason, data } = body;
    this.cmd = cmd;
    this.code = code;
    this.reason = reason;
    this.data = data;
    this.name = Object.keys(ErrorCode).find((name) => ErrorCode[name] === this.cmd);
    this.desc = ErrorCodeDesc[this.cmd];
    console.warn(this);
  }
}

/**
 * 响应错误
 */
export class RequestError {
  name = 'RequestError';

  desc = '请求错误';

  request = null;

  error = null;

  /**
   * @param request
   */
  constructor(e, request) {
    this.request = request;
    this.error = e;
    console.warn(this);
  }
}

export class NetworkError {
  name = 'NetworkError';
}
